#include "Logger.h"
#include "spdlog/sinks/basic_file_sink.h"

#include <iostream>
#include <memory>
#include <spdlog/async_logger.h>
#include <spdlog/common.h>
#include <spdlog/details/thread_pool.h>
#include <spdlog/spdlog-inl.h>
#include <vector>

using std::vector;

Logger& Logger::getInstance()
{
    static Logger instance;
    return instance;
}

void Logger::setLevel(spdlog::level::level_enum level)
{
    getInstance()._logger->set_level(level);
}

void Logger::init(const string &log_name, const string &filepath,
                  size_t queue_size,
                  size_t thread_count,
                  spdlog::async_overflow_policy policy)
{
    try
    {
        Logger &loggerInstance = getInstance();

        //初始化线程池
        loggerInstance._threadpool = std::make_shared<spdlog::details::thread_pool>(queue_size, thread_count);
        // 控制台输出
        vector<spdlog::sink_ptr> sinks;
        sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
        // 可选：文件输出
        if (!filepath.empty())
        {
            sinks.push_back(
                std::make_shared<spdlog::sinks::basic_file_sink_mt>
                (filepath));
        }

        loggerInstance._logger = std::make_shared<spdlog::logger>(log_name, sinks.begin(), sinks.end(), 
                                                                  loggerInstance._threadpool, policy); // 创建日志器
        loggerInstance._logger->set_level(spdlog::level::trace); // 设置日志级别
        loggerInstance._logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [net] %v"); // 设置日志格式

        // 注册日志器
        spdlog::register_logger(loggerInstance._logger);
        spdlog::set_default_logger(loggerInstance._logger);
    }
    catch (const spdlog::spdlog_ex &ex)
    {
        throw std::runtime_error("Logger init failed: " + string(ex.what()));
    }
}

void Logger::shutdown()
{
    Logger &instance = getInstance();
    if(instance._logger)
    {
        instance.flush();
        spdlog::drop(instance._logger->name()); // 反注册
    }
    instance._threadpool.reset(); // 释放线程池
}

void Logger::flush()
{
    if(auto &instance = getInstance(); instance._logger)
    {
        instance._logger->flush();
    }
}
